/* Darren Mui - CS362 - Random Tests on Sea Hag */
#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

#define NOISY_TEST 1

int main () {
	int i, r, n, p;

	int currPlayer;
	int topDeckBef[MAX_PLAYERS];
	int topDiscardBef[MAX_PLAYERS];
	int topDeckAft[MAX_PLAYERS];
	int topDiscardAft[MAX_PLAYERS];
	int check1, check2, check3;
	int check1toggle, check2toggle, check3toggle;

	SelectStream(2);
	PutSeed(3);

	struct gameState G;

	printf ("Testing Sea Hag with Random Tests.\n");

	check1 = 0;
	check2 = 0;
	check3 = 0;
	check1toggle = 0;
	check2toggle = 0;
	check3toggle = 0;

	for (n = 0; n < 100; n++) {
		printf("TEST %d\n", n);

		for (i = 0; i < sizeof(struct gameState); i++) {
			((char*)&G)[i] = floor(Random() * 256);
		}

		/* randomize number of players from 0 to MAX_PLAYERS, but will randomize until it's a valid number (between 2 to MAX_PLAYERS),
		   there is probably a simpler way to write this, but I am too unfamiliar with Random() to do so */
		do {
			G.numPlayers = floor(Random() * MAX_PLAYERS + 1);
		} while (G.numPlayers < 2);

		// randomize whose turn it is
		p = floor(Random() * G.numPlayers); 
		G.whoseTurn = p;

		for (currPlayer = 0; currPlayer < G.numPlayers; currPlayer++){
			G.deckCount[currPlayer] = floor(Random() * MAX_DECK); // randomize # of cards in deck for player
			//set each card in the player deck to a random card from curse to treasure_map (based on the enum in dominion.h)
			for (i = 0; i < G.deckCount[currPlayer]; i++) {
				G.deck[currPlayer][i] = floor(Random() * treasure_map);
			}

			G.discardCount[currPlayer] = floor(Random() * MAX_DECK); // randomize # of cards in discard for player
			//set each card in the player discard to a random card from curse to treasure_map (based on the enum in dominion.h)
			for (i = 0; i < G.discardCount[currPlayer]; i++) {
				G.discard[currPlayer][i] = floor(Random() * treasure_map);
			}

			G.handCount[currPlayer] = floor(Random() * MAX_HAND); // randomize # of cards in player hand
			//set each card in the player hand to a random card from curse to treasure_map (based on the enum in dominion.h)
			for (i = 0; i < G.handCount[currPlayer]; i++) {
				G.hand[currPlayer][i] = floor(Random() * treasure_map);
			}

			topDeckBef[currPlayer] = G.deck[currPlayer][G.deckCount[currPlayer] - 1];
			topDiscardBef[currPlayer] = G.discard[currPlayer][G.discardCount[currPlayer] - 1];
		}

		r = cardEffect(sea_hag, -1, -1, -1, &G, -1, 0); // play sea hag
		assert(r == 0);
	
		#if (NOISY_TEST == 1)
			printf("Player %d plays Sea Hag!\n", G.whoseTurn);
		#endif

		for (currPlayer = 0; currPlayer < G.numPlayers; currPlayer++) {
			topDeckAft[currPlayer] = G.deck[currPlayer][G.deckCount[currPlayer] - 1];
			topDiscardAft[currPlayer] = G.discard[currPlayer][G.discardCount[currPlayer] - 1];
			#if (NOISY_TEST == 1)
				printf("Player %d Before -> Top Deck enum: %d\tTop Discard enum: %d\n", currPlayer, topDeckBef[currPlayer], topDiscardBef[currPlayer]);
				printf("Player %d After  -> Top Deck enum: %d\tTop Discard enum: %d\n", currPlayer, topDeckAft[currPlayer], topDiscardAft[currPlayer]);
			#endif

			// for all players but the one playing sea hag...
			if (currPlayer != G.whoseTurn) {
				// if top card of discard is NOT the same as the top card from before playing Sea Hag
				if (topDiscardAft[currPlayer] != topDeckBef[currPlayer]) {
					check1toggle = 1;
				}
				// if top card of deck after playing Sea Hag is not a curse
				if (topDeckAft[currPlayer] != curse) {
					check2toggle = 1;
				}
			}
		}
		// if top cards of deck and discard for the player who played Sea Hag are affected after playing Sea Hag
		if (topDeckBef[G.whoseTurn] != topDeckAft[G.whoseTurn] || topDiscardBef[G.whoseTurn] != topDiscardAft[G.whoseTurn]) {
			check3toggle = 1;
		}

		if (check1toggle == 1) {
			check1++;
			check1toggle = 0;
		}
		if (check2toggle == 1) {
			check2++;
			check2toggle = 0;
		}
		if (check3toggle == 1) {
			check3++;
			check3toggle = 0;
		}

		printf("\n");


	}

	printf("TESTS COMPLETE\n");
	printf("In %d tests, the top card of the deck was not discarded to the top of the discard pile properly\n", check1);
	printf("In %d tests, the top card of the deck was not a curse after playing Sea Hag\n", check2);
	printf("In %d tests, the player who played Sea Hag also had their deck affected somehow\n", check3);

	return 0;
}
